import 'package:socket_io_client/socket_io_client.dart' as socket_io;
import 'package:untitled/core/socket/socket_events.dart';
import 'package:untitled/core/socket/socket_models/send_error_payload.dart';
import 'package:untitled/core/socket/socket_models/send_heartbeat_payload.dart';

typedef EventCallback<T> = void Function(T data);

class TypedSocketService {
  final socket_io.Socket _socket;

  // 事件名 -> 回调列表
  final Map<String, List<Function>> _listeners = {};

  TypedSocketService(this._socket);

  void on<T>(SocketEvent event, EventCallback<T> callback, T Function(dynamic) fromJson) {
    final eventName = event.name;

    _listeners.putIfAbsent(eventName, () => []).add(callback);

    // 只第一次绑定底层socket监听
    if (_listeners[eventName]!.length == 1) {
      _socket.on(eventName, (rawData) {
        final data = fromJson(rawData);
        for (final listener in _listeners[eventName]!) {
          (listener as EventCallback<T>)(data);
        }
      });
    }
  }

  void off(SocketEvent event) {
    final eventName = event.name;
    _listeners.remove(eventName);
    _socket.off(eventName);
  }

  void onSendMessage(EventCallback<SendMessagePayload> cb) =>
      on<SendMessagePayload>(
          SocketEvent.sendMessage,
          cb,
              (data) => SendMessagePayload.fromJson(Map<String, dynamic>.from(data)));

  void emitSendMessage(SendMessagePayload payload) =>
      emit(SocketEvent.sendMessage, payload.toJson());

  void onSendError(EventCallback<SendErrorPayload> cb) =>
      on<SendErrorPayload>(
          SocketEvent.sendError,
          cb,
              (data) => SendErrorPayload.fromJson(Map<String, dynamic>.from(data)));

  void emitSendError(SendErrorPayload payload) =>
      emit(SocketEvent.sendError, payload.toJson());

  void emitSendHeartbeat(SendHeartbeatPayload play) =>
      emit(SocketEvent.sendHeartBeat, play.toJson());

  void emit(SocketEvent event, Map<String, dynamic> json) {
    _socket.emit(event.name, json);
  }
}
